import random
import socket
import pygame
import time
import sys
from map import Map
from chess import ChessPieces
# import gevent
# from gevent import monkey
import re

__author__ = {'name': '幻π园长',
              'mail': 'xe333@sina.com',
              'Version': '1.1局域网联机版'}
win_x = 560
win_y = 640
IP = '192.168.84.52'

class Game(object):
    """
    默认黑棋
    """
    def __init__(self):
        self.gameovered = False
        self.pressdown = False
        pygame.init()
        self.window = pygame.display.set_mode([win_x, win_y])
        self.set_window()
        self.map = Map(self.window)
        self.chesses = []
        self.white = []
        self.black = []
        self.turn = True
        self.loading()
        self.clk_chess = False
        self.a, self.b = 0, 0
        self.cka, self.ckb = 64, 64
        self.selected = pygame.image.load("res/select.png")

    @staticmethod
    def set_window():
        pygame.display.set_caption('五步棋(黑棋)                made by 幻π园长')
        win_ico = pygame.image.load('res/logo.png')
        pygame.display.set_icon(win_ico)

    def events(self):
        """处理事件的方法"""
        # 事件的处理
        event_list = pygame.event.get()
        for event in event_list:
            if event.type == pygame.QUIT:
                print("关闭了窗口")
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                pressed = pygame.mouse.get_pressed()
                for index in range(len(pressed)):
                    if pressed[index]:
                        # 获得点击
                        if index == 0:
                            self.pressdown = True  # 传送点击信号
                            self.a, self.b = pygame.mouse.get_pos()
                            # print(self.a, self.b)
                            self.a, self.b = self.a // 80, self.b // 80
                            if self.a < 0:
                                self.a = 0
                            if self.b < 0:
                                self.b = 0
                            # print(self.a, self.b)

    def blit(self):
        """各个对象的绘制（把图片摆放到需要的位置）"""
        self.map.blited()
        self.window.blit(self.selected, (self.cka * 80 + 12, self.ckb * 80 + 14))
        for i in self.chesses:
            i.blited((i.pos[0]) * 80 + 14, i.pos[1] * 80 + 16)


    @staticmethod
    def update():
        """更新界面"""
        pygame.display.update()

    def loading(self):
        valuess = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
        for i in range(1, 6):
            j = valuess[random.randrange(len(valuess))]
            valuess.remove(j)
            onepiece = ChessPieces(True, j, i, 0, self.window)
            self.map.mappy[(i, 0)] = onepiece
            # self.white.append(onepiece)
            self.chesses.append(onepiece)
            self.white.append(onepiece)
            j = valuess[random.randrange(len(valuess))]
            valuess.remove(j)
            onepiece = ChessPieces(True, j, i, 2, self.window)
            # self.white.append(onepiece)
            self.chesses.append(onepiece)
            self.white.append(onepiece)
            self.map.mappy[(i, 2)] = onepiece
        valuess = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
        for i in range(1, 6):
            j = valuess[random.randrange(len(valuess))]
            valuess.remove(j)
            onepiece = ChessPieces(False, j, i, 5, self.window)
            # self.black.append(onepiece)
            self.chesses.append(onepiece)
            self.black.append(onepiece)
            self.map.mappy[(i, 5)] = onepiece
            j = valuess[random.randrange(len(valuess))]
            valuess.remove(j)
            onepiece = ChessPieces(False, j, i, 7, self.window)
            # self.black.append(onepiece)
            self.chesses.append(onepiece)
            self.black.append(onepiece)
            self.map.mappy[(i, 7)] = onepiece

    def act(self, conn):
        self.events()
        try:
            sendmessage(self, conn)
        except ConnectionResetError:
            self.write('与远程主机失去连接，请重试。', 40, 260)
        # 白棋
        if self.turn:
            a, b = conn.geta, conn.getb
        else:
            a, b = self.a, self.b
        if not self.clk_chess:
            if self.map.mappy[(a, b)] is not None:
                if self.map.mappy[(a, b)].horde == self.turn:
                    self.clk_chess = True
                    self.cka, self.ckb = a, b
                    if self.map.mappy[(a, b)].horde == self.turn and not self.map.mappy[(a, b)].exposure:
                        self.map.mappy[(a, b)].exposure = True
                        self.map.mappy[(a, b)].expose()
                        # send('白棋翻了a, b的棋子')
        if self.clk_chess:
            # 切换棋子
            if (self.map.mappy[(a, b)] is not None) and (
                    self.map.mappy[(self.cka, self.ckb)].actualvalue == self.map.mappy[(self.cka, self.ckb)].value):
                if (self.map.mappy[(a, b)].horde == self.map.mappy[(self.cka, self.ckb)].horde) and self.map.mappy[(a, b)].exposure:
                    if self.map.mappy[(self.cka, self.ckb)].changeche:
                        self.cka, self.ckb = a, b
            # 能走的时候
            if self.map.mappy[(self.cka, self.ckb)].actualvalue > 0:
                self.move(a, b)
                self.map.mappy[(self.cka, self.ckb)].changeche = True  # 空与不空、能不能走的判断放进去做
            if self.map.mappy[(self.cka, self.ckb)].actualvalue == 0:
                self.map.mappy[(self.cka, self.ckb)].actualvalue = self.map.mappy[(a, b)].value
                self.turn = not self.turn
                # print('切换成功')
                self.clk_chess = False
                # print('白棋罢手')
                # send('白棋走完了')
                self.cka, self.ckb = 64, 64
                self.a, self.b = 64, 64
                # print(self.cka, self.ckb)
        # # 黑棋
        # if not self.turn:
        #     a, b = self.a, self.b
        #     # print(self.clk_chess)
        #     if not self.clk_chess:
        #         if self.map.mappy[(a, b)] is not None:
        #             if not self.map.mappy[(a, b)].horde:
        #                 self.clk_chess = True
        #                 # print('选中黑棋')
        #                 self.cka, self.ckb = a, b
        #                 if (not self.map.mappy[(a, b)].horde) and (not self.map.mappy[(a, b)].exposure):
        #                     self.map.mappy[(a, b)].exposure = True
        #                     self.map.mappy[(a, b)].expose()
        #                     # send('黑棋翻了a, b的棋子')
        #     if self.clk_chess:
        #         if (self.map.mappy[(a, b)] is not None) and (
        #                 self.map.mappy[(self.cka, self.ckb)].actualvalue == self.map.mappy[(self.cka, self.ckb)].value):
        #             if (self.map.mappy[(a, b)].horde == self.map.mappy[(self.cka, self.ckb)].horde) and self.map.mappy[(a, b)].exposure:
        #                 if self.map.mappy[(self.cka, self.ckb)].changeche:
        #                     self.cka, self.ckb = a, b
        #         if self.map.mappy[(self.cka, self.ckb)].actualvalue > 0:
        #             self.move(a, b)  # 空与不空、能不能走的判断放进去做
        #             self.map.mappy[(self.cka, self.ckb)].changeche = True
        #         if self.map.mappy[(self.cka, self.ckb)].actualvalue == 0:
        #             self.map.mappy[(self.cka, self.ckb)].actualvalue = self.map.mappy[(a, b)].value
        #             self.turn = True
        #             self.clk_chess = False
        #             # send('黑棋走完了')
        #             self.cka, self.ckb = 0, 0

    def move(self, x, y):
        a, b = self.cka, self.ckb
        # print(x, y)
        # 空与不空、能不能走的判断在这里做
        if (abs(x - a) < 2) and (abs(y - b) < 2) and (abs(x + y - a - b) == 1) and (self.map.mappy[(x, y)] is None):
            self.map.mappy[(a, b)].pos = [x, y]
            self.map.mappy[(a, b)].actualvalue -= 1
            # send('a, b位置的棋子要走了')
            self.map.mappy[(x, y)] = self.map.mappy[(a, b)]
            self.map.mappy[(a, b)] = None
            self.cka, self.ckb = x, y
            # print(self.cka, self.ckb)
            # send('走到了x, y 位置')
        if (abs(x - a) < 2) and (abs(y - b) < 2) and (abs(x + y - a - b) == 1) and (self.map.mappy[(x, y)] is not None):
            if self.map.mappy[(x, y)].horde != self.turn:
                self.chesses.remove(self.map.mappy[(x, y)])
                if self.map.mappy[(x, y)].horde:
                    self.white.remove(self.map.mappy[(x, y)])
                if not self.map.mappy[(x, y)].horde:
                    self.black.remove(self.map.mappy[(x, y)])
                self.map.mappy[(a, b)].pos = [x, y]
                self.map.mappy[(a, b)].actualvalue -= 1
                # send('a, b位置的棋子要走了')
                self.map.mappy[(x, y)] = self.map.mappy[(a, b)]
                # send('走到了x, y 位置')
                self.map.mappy[(a, b)] = None
                self.cka, self.ckb = x, y
                if len(self.white) == 0:
                    self.gameover()
                if len(self.black) == 0:
                    self.gameover()

    def write(self, text, size, y):
        font = pygame.font.SysFont('SimHei', size)
        # render(text(文本内容), antialias(抗锯齿), color(RGB))，返回文字对象
        textobj = font.render(text, 1, (30, 50, 200))

        # 设置文字矩形对象位置
        textrect = textobj.get_rect()
        textrect.move_ip(win_x / 2 - textrect[2] / 2, y)
        # 在指定位置绘制指定文字对象
        self.window.blit(textobj, textrect)
        # 更新界面
        pygame.display.update()

    def run(self, conn):
        self.act(conn)
        self.blit()
        self.update()

    def gamebegin(self, conn):
        self.map.blited()  # 显示开始界面的背景
        self.write("正在连接主机", 50, 150)
        try:
            conn.client_soc.connect((IP, 12138))
        except ConnectionError:
            self.write('找不到主机', 40, 260)
        else:
            self.write("连接成功，按下ENTER开始游戏", 40, 240)
            self.wait_for_player_input()

    def gameover(self):
        self.gameovered = True
        # 停止背景音乐
        pygame.mixer.music.stop()
        # 加载音效
        boom_sound = pygame.mixer.Sound("./res/gameover.wav")
        # 播放音效
        boom_sound.play()
        self.write("游戏结束", 50, 150)
        self.write("按Enter键关闭窗口", 40, 230)
        self.wait_for_player_input()

    @staticmethod
    def wait_for_player_input():
        while True:
            # 事件的处理
            event_list = pygame.event.get()
            for event in event_list:
                # 1. 鼠标点击关闭窗口事件
                if event.type == pygame.QUIT:
                    print("关闭了窗口")
                    sys.exit()

                # 2. 键盘按下事件
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_RETURN:
                        return


class Connecting(object):
    def __init__(self):
        self.geta, self.getb = 0, 0
        self.client_soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # self.tcp_soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

        # self.tcp_soc.listen()
        # self.client_soc, self.addr = self.tcp_soc.accept()


def sendmessage(game, conn):
    if not game.turn:
        senddata = '---' + str(game.a)+','+str(game.b)
        print(senddata)
        conn.client_soc.send(senddata.encode('utf-8'))
    if game.turn:
        recvdata = conn.client_soc.recv(4096)
        # print(recvdata)
        # time.sleep(0.1)
        if recvdata:
            recvdata = recvdata
            # print(content)
            recvdata = re.search(r'[^-]+', recvdata.decode('utf-8'))
            # print(recvdata.group())
            conn.geta, conn.getb = eval(recvdata.group())
            print(conn.geta, conn.getb)


def getmessage(game, conn):
    while 1:
        recvdata = conn.client_soc.recv(4096)
        if recvdata:
            recvdata = recvdata.decode('utf-8')
            recvdata = re.search(r'[^/]+', recvdata)
            # print('loading received:', recvdata.group())
            recvdata = eval(recvdata.group())
            for i in range(20):
                game.chesses[i].value = recvdata[i]
                game.chesses[i].actualvalue = game.chesses[i].value
            game.write('game loading……', 40, 260)
            break
    time.sleep(5)


def main():
    # monkey.patch_all()
    game = Game()
    conn = Connecting()
    game.gamebegin(conn)
    getmessage(game, conn)
    # g1 = gevent.spawn(game.run, conn)
    # g2 = gevent.spawn(sendmessage, game, conn)
    while 1:
        # g1.join()
        # g2.join()
        game.run(conn)
        if game.gameovered:
            break
    conn.client_soc.close()


if __name__ == '__main__':
    main()
